<template>
  <div>
    <editor-content :editor="editor" />
    <div class="editor-actions">
      <button @click="insertTemplateVariable">插入模板变量</button>
      <button @click="convertTemplateVariables">转换模板变量</button>
      <!-- 新增获取文本按钮 -->
      <button @click="getEditorText" class="btn-primary">获取文本内容</button>
      <!-- 新增调试按钮 -->
      <button @click="printEditorNodes" class="btn-primary">打印节点树</button>
      <!-- 新增持久化测试按钮 -->
      <button @click="saveToStorage" class="btn-success">保存到本地</button>
      <button @click="loadFromStorage" class="btn-success">从本地恢复</button>
      <button @click="clearStorage" class="btn-warning">清空本地存储</button>
      <button @click="testPersistence" class="btn-info">测试持久化</button>
      <!-- 新增复制测试按钮 -->
      <button @click="testCopy" class="btn-warning">测试复制功能</button>
      <!-- 新增demo测试按钮 -->
      <button @click="testTwoFormats" class="btn-demo">测试两种格式</button>
      <button @click="testValueVariable" class="btn-demo">测试值变量</button>
      <button @click="testPlaceholderVariable" class="btn-demo">测试占位符变量</button>
    </div>

    <!-- 持久化状态显示 -->
    <div class="persistence-status" v-if="persistenceStatus">
      <p :class="persistenceStatus.type">{{ persistenceStatus.message }}</p>
    </div>

    <!-- 调试信息区域 -->
    <div class="debug-info" v-if="debugMode">
      <h4>调试信息</h4>
      <p>模板变量节点类型: {{ nodeTypeExists ? "已注册" : "未注册" }}</p>
      <p>当前选中位置: {{ currentPos }}</p>
      <button @click="testTemplateEdit">测试编辑变量</button>
    </div>

    <!-- 新增文本内容展示区域 -->
    <div v-if="editorTextContent" class="text-content-display">
      <h4>编辑器文本内容：</h4>
      <pre>{{ editorTextContent }}</pre>
      <button @click="editorTextContent = null" class="close-btn">关闭</button>
    </div>
  </div>
</template>

<script>
import Code from "@tiptap/extension-code";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
import Typography from "@tiptap/extension-typography";
import { Editor, EditorContent } from "@tiptap/vue-3";

import { ColorHighlighter } from "./ColorHighlighter.ts";
import { SmilieReplacer } from "./SmilieReplacer.ts";
import { TemplateVariable ,convertTemplateVariables } from "./TemplateVariableNode.ts";
import "./template-variable.css"; // 引入模板变量样式
import { Plugin, PluginKey } from "@tiptap/pm/state";

export default {
  components: {
    EditorContent,
  },

  data() {
    return {
      editor: null,
      debugMode: true,
      nodeTypeExists: false,
      currentPos: null,
      editorTextContent: null,
      persistenceStatus: null, // 新增持久化状态
      storageKey: 'tiptap-editor-content', // localStorage 键名
      autoSaveInterval: null, // 自动保存定时器
    };
  },

  mounted() {
    try {
      this.editor = new Editor({
        extensions: [
          Document,
          Paragraph,
          Text,
          Code,
          Typography,
          ColorHighlighter,
          SmilieReplacer,
          TemplateVariable,
        ],
        content: this.getInitialContent(), // 使用持久化内容或默认内容
        onCreate: ({ editor }) => {
          this.initEditor(editor);
        },
        onSelectionUpdate: ({ editor }) => {
          this.currentPos = editor.state.selection.from;
        },
        onUpdate: ({ editor }) => {
          // 内容更新时自动保存（防抖）
          this.debouncedAutoSave();
        },
      });
    } catch (error) {
      console.error("编辑器创建错误:", error);
    }
  },

  methods: {
    // 获取初始内容（优先从 localStorage 恢复）
    getInitialContent() {
      const savedDocJson = this.loadDocFromStorage();
      if (savedDocJson) {
        this.showPersistenceStatus('从本地存储恢复文档结构', 'success');
        return savedDocJson;
      }

      // 默认内容
      return `帮我给{{[内蒙古羊肉产品]}}写{{[10]}}个广告创意文案，文案风格为专业的、吸睛的，要求每个广告创意文案的字数控制在{{[数字]}}左右，每个创意文案不重复，有明显的差异。`;
    },

    // 初始化编辑器
    initEditor(editor) {
      this.nodeTypeExists = !!editor.schema.nodes.templateVariable;
      console.log("模板变量节点类型是否存在:", this.nodeTypeExists);

      if (this.nodeTypeExists) {
        convertTemplateVariables(editor);
      }
    },

    // 插入模板变量
    insertTemplateVariable() {
      const content = prompt("请输入模板变量内容:", "变量名");
      if (!content || !this.editor) return;

      try {
        this.editor
          .chain()
          .focus()
          .insertContent({
            type: "templateVariable",
            attrs: {
              inputValue: content,
              placeholder: content
            }
          })
          .run();
      } catch (error) {
        console.error("插入模板变量失败:", error);
        // 备用方法
        this.editor.chain().focus().insertContent(`{{${content}}}`).run();

        setTimeout(() => convertTemplateVariables(this.editor), 100);
      }
    },

    // 测试编辑变量
    testTemplateEdit() {
      const content = prompt("输入测试变量内容:");
      if (!content || !this.editor) return;

      this.editor
        .chain()
        .focus()
        .insertContent({
          type: "templateVariable",
          attrs: {
            inputValue: content,
            placeholder: content
          }
        })
        .run();
    },

    // 新增：打印当前tiptap的node树
    printEditorNodes() {
      if (!this.editor) return;
      // 打印 ProseMirror Node 的 JSON 结构
      const docJson = this.editor.state.doc.toJSON();
      console.log('当前编辑器节点树:', docJson);
      console.log('当前编辑器 HTML:', this.editor.getHTML());

      // 额外显示存储的数据
      const savedData = localStorage.getItem(this.storageKey);
      if (savedData) {
        console.log('本地存储的数据:', JSON.parse(savedData));
      }
    },

    // 获取编辑器文本内容
    getEditorText() {
      if (!this.editor) return;

      try {
        // 获取HTML内容
        const html = this.editor.getHTML();

        // 获取纯文本内容，包括模板变量的当前值和换行
        let text = "";
        let isFirstParagraph = true;

        this.editor.state.doc.descendants((node, pos, parent) => {
          if (node.type.name === "paragraph") {
            // 段落开始时添加换行符（除了第一个段落）
            if (!isFirstParagraph) {
              text += "\n";
            }
            isFirstParagraph = false;
          } else if (node.type.name === "templateVariable") {
            // 使用正确的属性名 inputValue
            const variableContent = node.attrs.inputValue || node.attrs.placeholder || "";
            text += variableContent;
          } else if (node.isText) {
            text += node.text;
          }
          return true;
        });

        // 设置结果到视图变量
        this.editorTextContent = {
          plainText: text,
          html: html,
        };
      } catch (error) {
        console.error("获取编辑器文本失败:", error);
        this.editorTextContent = { error: "获取文本时发生错误" };
      }
    },

    // 保存文档结构到 localStorage
    saveToStorage() {
      if (!this.editor) return;

      try {
        // 使用 editor.state.doc.toJSON() 保存完整的文档结构
        const docJson = this.editor.state.doc.toJSON();
        const contentData = {
          docJson: docJson,
          html: this.editor.getHTML(), // 同时保存 HTML 用于调试
          timestamp: Date.now(),
          version: '2.0' // 升级版本号
        };

        localStorage.setItem(this.storageKey, JSON.stringify(contentData));
        this.showPersistenceStatus('文档结构已保存到本地存储', 'success');
        console.log('文档结构已保存:', contentData);
      } catch (error) {
        console.error('保存失败:', error);
        this.showPersistenceStatus('保存失败: ' + error.message, 'error');
      }
    },

    // 从 localStorage 恢复文档结构
    loadFromStorage() {
      const savedDocJson = this.loadDocFromStorage();
      if (savedDocJson && this.editor) {
        try {
          // 使用 editor.commands.setContent 恢复文档结构
          this.editor.commands.setContent(savedDocJson);
          this.showPersistenceStatus('文档结构已从本地存储恢复', 'success');

          // 由于文档结构已经包含模板变量节点，不需要重新转换
          console.log('文档结构恢复完成');
        } catch (error) {
          console.error('恢复文档结构失败:', error);
          this.showPersistenceStatus('恢复文档结构失败: ' + error.message, 'error');
        }
      } else {
        this.showPersistenceStatus('没有找到本地存储的文档结构', 'warning');
      }
    },

    // 从 localStorage 加载文档结构（内部方法）
    loadDocFromStorage() {
      try {
        const savedData = localStorage.getItem(this.storageKey);
        if (savedData) {
          const contentData = JSON.parse(savedData);
          console.log('加载的文档数据:', contentData);

          // 优先使用 docJson，如果不存在则使用 html（向后兼容）
          if (contentData.docJson) {
            return contentData.docJson;
          } else if (contentData.html) {
            // 兼容旧版本的 HTML 格式
            console.log('使用旧版 HTML 格式，建议重新保存');
            return contentData.html;
          }
        }
      } catch (error) {
        console.error('加载文档结构失败:', error);
        this.showPersistenceStatus('加载文档结构失败: ' + error.message, 'error');
      }
      return null;
    },

    // 清空本地存储
    clearStorage() {
      try {
        localStorage.removeItem(this.storageKey);
        this.showPersistenceStatus('本地存储已清空', 'success');
        console.log('本地存储已清空');
      } catch (error) {
        console.error('清空存储失败:', error);
        this.showPersistenceStatus('清空存储失败: ' + error.message, 'error');
      }
    },

    // 测试持久化功能
    testPersistence() {
      if (!this.editor) return;

      // 添加测试内容，包含模板变量
      const testVariableContent = `测试变量${Math.floor(Math.random() * 100)}`;
      const testContent = `\n\n测试持久化 - ${new Date().toLocaleTimeString()}：`;

      // 先插入普通文本
      this.editor.chain().focus().insertContent(testContent).run();

      // 然后插入模板变量节点
      setTimeout(() => {
        try {
          this.editor.chain().focus().insertContent({
            type: "templateVariable",
            attrs: {
              inputValue: testVariableContent,
              placeholder: testVariableContent
            }
          }).run();

          // 立即保存文档结构
          setTimeout(() => {
            this.saveToStorage();
            this.showPersistenceStatus('测试内容（包含模板变量）已添加并保存，可以刷新页面测试恢复功能', 'info');
          }, 100);
        } catch (error) {
          console.error('插入测试模板变量失败:', error);
          // 备用方案：插入文本格式
          this.editor.chain().focus().insertContent(`{{${testVariableContent}}}`).run();

          setTimeout(() => {
            convertTemplateVariables(this.editor);
            this.saveToStorage();
            this.showPersistenceStatus('测试内容已添加并保存（使用文本转换），可以刷新页面测试恢复功能', 'info');
          }, 200);
        }
      }, 50);
    },

    // 更新复制测试功能，改进多节点处理
    testCopy() {
      if (!this.editor) return;

      const { from, to } = this.editor.state.selection;
      if (from === to) {
        // 如果没有选择，创建一个测试选择
        this.editor.commands.selectAll();
        this.showPersistenceStatus('已选择全部内容，请手动复制（Ctrl+C）测试', 'info');
        return;
      }

      try {
        console.log('选择范围:', { from, to });
        console.log('DOM 映射状态:', this.editor.domMapping);

        // 获取选择范围内的纯文本内容
        let selectedText = '';
        const selectedContent = this.editor.state.doc.slice(from, to);

        console.log('选择的内容结构:', selectedContent.toJSON());

        // 优先使用插件的 clipboardTextSerializer
        const plugins = this.editor.extensionManager.extensions.find(ext =>
          ext.name === 'templateVariable'
        );

        if (plugins && plugins.options.addProseMirrorPlugins) {
          const pluginInstance = plugins.options.addProseMirrorPlugins().find(p =>
            p.key && p.key.key === 'templateVariableCopy'
          );

          if (pluginInstance && pluginInstance.props.clipboardTextSerializer) {
            selectedText = pluginInstance.props.clipboardTextSerializer(selectedContent, this.editor.view);
            console.log('使用插件序列化器获取的文本:', selectedText);
          }
        }

        // 备用方案：手动遍历
        if (!selectedText) {
          console.log('使用备用方案处理复制');
          let paragraphTexts = [];

          selectedContent.content.descendants((node, pos, parent, index) => {
            if (node.type.name === 'paragraph') {
              let paragraphText = '';

              node.descendants((childNode, childPos) => {
                if (childNode.type.name === 'templateVariable') {
                  // 计算绝对位置
                  const absolutePos = from + pos + 1 + childPos; // +1 for paragraph node
                  let actualValue = '';

                  console.log('处理模板变量，位置:', absolutePos);

                  if (this.editor.domMapping) {
                    // 查找最匹配的 DOM 元素
                    let bestMatch = null;
                    let minDistance = Infinity;

                    for (let [mappedPos, domElement] of this.editor.domMapping.entries()) {
                      const distance = Math.abs(mappedPos - absolutePos);
                      console.log(`位置 ${mappedPos} 距离目标 ${absolutePos} 的距离: ${distance}`);
                      if (distance < minDistance) {
                        minDistance = distance;
                        bestMatch = { pos: mappedPos, element: domElement, distance };
                      }
                    }

                    console.log('最佳匹配:', bestMatch);

                    if (bestMatch && bestMatch.distance <= 3 && bestMatch.element.value !== undefined) {
                      actualValue = bestMatch.element.value;
                      console.log('使用 DOM 值:', actualValue);
                    }
                  }

                  // 如果没有找到 DOM 值，使用节点属性
                  if (!actualValue) {
                    actualValue = childNode.attrs.inputValue || childNode.attrs.placeholder || '';
                    console.log('使用节点属性值:', actualValue);
                  }

                  paragraphText += actualValue;
                } else if (childNode.isText) {
                  paragraphText += childNode.text;
                }
                return true;
              });

              paragraphTexts.push(paragraphText);
            }
            return false; // 不深入段落内部，我们已经处理了
          });

          selectedText = paragraphTexts.join('\n');
        }

        // 显示将要复制的内容
        console.log('最终复制内容:', selectedText);
        this.showPersistenceStatus(`选择的内容: "${selectedText.trim()}"`, 'info');

        // 手动设置剪贴板内容
        if (navigator.clipboard && navigator.clipboard.writeText) {
          navigator.clipboard.writeText(selectedText.trim()).then(() => {
            this.showPersistenceStatus('内容已复制到剪贴板', 'success');
          }).catch(error => {
            console.error('复制失败:', error);
            this.showPersistenceStatus('复制失败: ' + error.message, 'error');
          });
        } else {
          // 备用方案：使用 execCommand
          const textArea = document.createElement('textarea');
          textArea.value = selectedText.trim();
          document.body.appendChild(textArea);
          textArea.select();
          try {
            document.execCommand('copy');
            this.showPersistenceStatus('内容已复制到剪贴板（备用方案）', 'success');
          } catch (error) {
            console.error('备用复制方案失败:', error);
            this.showPersistenceStatus('复制失败: ' + error.message, 'error');
          } finally {
            document.body.removeChild(textArea);
          }
        }

      } catch (error) {
        console.error('复制测试失败:', error);
        this.showPersistenceStatus('复制测试失败: ' + error.message, 'error');
      }
    },

    // 防抖自动保存
    debouncedAutoSave() {
      if (this.autoSaveInterval) {
        clearTimeout(this.autoSaveInterval);
      }

      this.autoSaveInterval = setTimeout(() => {
        this.saveToStorage();
      }, 2000); // 2秒后自动保存
    },

    // 显示持久化状态消息
    showPersistenceStatus(message, type) {
      this.persistenceStatus = { message, type };

      // 3秒后自动隐藏消息
      setTimeout(() => {
        this.persistenceStatus = null;
      }, 3000);
    },

    // 新增：测试两种变量格式
    testTwoFormats() {
      const content = '用户名: {{请输入用户名}} 当前用户: ${{张三}} 年龄: ${{25}} 地址: {{请输入地址}}';
      this.editor.commands.setContent(content);

      setTimeout(() => {
        convertTemplateVariables(this.editor);
        this.showPersistenceStatus('转换完成：{{}} 是占位符，${{}} 是实际值', 'success');
      }, 100);
    },

    // 新增：测试值变量 ${{}}
    testValueVariable() {
      const content = '实际姓名：${{李四}} 实际电话：${{13800138000}} 实际年龄：${{30}}';
      this.editor.commands.setContent(content);

      setTimeout(() => {
        convertTemplateVariables(this.editor);
        this.showPersistenceStatus('值变量测试完成，${{}} 显示为实际值', 'success');
      }, 100);
    },

    // 新增：测试占位符变量 {{}}
    testPlaceholderVariable() {
      const content = '请输入姓名：{{姓名}} 请输入电话：{{电话}} 请输入年龄：{{年龄}}';
      this.editor.commands.setContent(content);

      setTimeout(() => {
        convertTemplateVariables(this.editor);
        this.showPersistenceStatus('占位符变量测试完成，{{}} 显示为占位符', 'success');
      }, 100);
    },
  },

  beforeUnmount() {
    // 清理定时器
    if (this.autoSaveInterval) {
      clearTimeout(this.autoSaveInterval);
    }

    // 最后保存一次
    if (this.editor) {
      this.saveToStorage();
    }

    this.editor?.destroy();
  },
};
</script>

<style lang="scss">
/* 基础编辑器样式 */

.tiptap {
  :first-child {
    margin-top: 0;
  }

  /* 代码样式 */
  code {
    background-color: var(--purple-light);
    border-radius: 0.4rem;
    color: var(--black);
    font-size: 0.85rem;
    padding: 0.25em 0.3em;
  }

  /* 颜色样例 */
  .color {
    white-space: nowrap;

    &::before {
      background-color: var(--color);
      border: 1px solid rgba(128, 128, 128, 0.3);
      border-radius: 2px;
      content: " ";
      display: inline-block;
      height: 1em;
      margin-bottom: 0.15em;
      margin-right: 0.1em;
      vertical-align: middle;
      width: 1em;
    }
  }
}

/* 编辑器操作按钮 */
.editor-actions {
  margin-top: 10px;

  button {
    margin-right: 8px;
    padding: 5px 10px;
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    border-radius: 3px;
    cursor: pointer;

    &:hover {
      background-color: #e0e0e0;
    }
  }
}

/* 调试信息区域 */
.debug-info {
  margin-top: 20px;
  padding: 10px;
  border: 1px dashed #999;
  background-color: #f9f9f9;

  h4 {
    margin-top: 0;
    margin-bottom: 10px;
    color: #666;
  }

  p {
    margin: 5px 0;
    font-family: monospace;
  }

  button {
    margin-top: 10px;
    background-color: #4c85e6;
    color: white;
    border: none;
    padding: 5px 10px;
    border-radius: 3px;
    cursor: pointer;
  }
}

/* 新增文本展示区域样式 */
.text-content-display {
  margin-top: 20px;
  padding: 15px;
  border: 1px solid #ddd;
  background-color: #f7f7f7;
  border-radius: 4px;
  position: relative;

  h4 {
    margin-top: 0;
    margin-bottom: 10px;
    color: #333;
  }

  pre {
    background-color: #fff;
    padding: 10px;
    border-radius: 3px;
    border: 1px solid #eee;
    overflow-x: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
    max-height: 300px;
    overflow-y: auto;
  }

  .close-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    background-color: #f44336;
    color: white;
    border: none;
    border-radius: 3px;
    padding: 3px 8px;
    cursor: pointer;
    font-size: 12px;

    &:hover {
      background-color: #d32f2f;
    }
  }
}

/* 新增持久化状态样式 */
.persistence-status {
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: 4px;

  p {
    margin: 0;
    font-weight: 500;

    &.success {
      background-color: #d4edda;
      color: #155724;
      border: 1px solid #c3e6cb;
    }

    &.error {
      background-color: #f8d7da;
      color: #721c24;
      border: 1px solid #f5c6cb;
    }

    &.warning {
      background-color: #fff3cd;
      color: #856404;
      border: 1px solid #ffeaa7;
    }

    &.info {
      background-color: #d1ecf1;
      color: #0c5460;
      border: 1px solid #bee5eb;
    }
  }
}

/* 样式化测试按钮 */
.btn-primary {
  background-color: #2196f3 !important;
  color: white !important;
}

.btn-success {
  background-color: #4caf50 !important;
  color: white !important;
}

.btn-warning {
  background-color: #ff9800 !important;
  color: white !important;
}

.btn-info {
  background-color: #00bcd4 !important;
  color: white !important;
}

/* Demo按钮样式 */
.btn-demo {
  background-color: #9c27b0 !important;
  color: white !important;
}
</style>
